from string import *
def get_stats(f, k, mem_limit, directory):
    """
    f(string) - name of file,
    k(integer) - k-mer length,
    mem_limit(integer) - memory available for one dictionary
    directory(string) - directory, where files containing stats will be saved

    creates several files, containing k-mers stats. the number of files depends on
    k and the available memory
    """

    def char(f):
        """
        returns the next symbol, not equal to newline,
        note that (f.read(1) == '') indicates end of file
        """
        c = f.read(1)
        if c == '\r' or c == '\n':
            return char(f)

        return c

    def save_dict(DICT, num, directory):
        """
        creates a new file in the given directory
        and writes content of DICT in it
        """
        out = open(directory + 'stat' + str(num) + '.txt', 'w')
        for key in DICT:
            out.write(str(key) + '     ' + str(DICT[key]) + '\n')
        out.close()

    def count(kmer, num):
        """
        kmer(string) is the last kmer read,
        num - iteration number, needed to generate the name of the file,
                                            where KMERS will e saved
        """

        KMERS = {} #keys are k-mers, values are occurences number of each k-mer
        eof = 0    #tracks the end of file
        mem = 0    #approximate amount of memory used(in bites)

        while mem <= mem_limit:
            mem += 12*(kmer not in KMERS) # == 12 if kmer not in KMERS
                                          # == 0 otherwise

            KMERS[kmer] = (KMERS.get(kmer, 0) + 1)
            newChar = char(f)
            if newChar == '':
                eof = 1
                break
            else:
                kmer = kmer[1:] + newChar

        save_dict(KMERS, num, directory)
        #print KMERS #save stats in file to clear memory
        if not eof:
            count(kmer, num + 1)


    K = k*2 #because every nucleotide encoded with two digits
    f.seek(0) #otherwise the second symbol in file may be read
    begin = f.read(K)
    count(begin, 0)

if __name__ == "__main__":
    infile = open('C:/py/sequence2.txt', 'rb')
    get_stats(infile, 5, 5000, 'C:/py/files/')
    infile.close()